package org.xhy.sniffer.plugins.springmvc;

import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.xhy.sniffer.match.AnnotationMatch;
import org.xhy.sniffer.match.ClassMatch;
import org.xhy.sniffer.plugin.ClassEnhancePluginDefine;
import org.xhy.sniffer.interceptor.ConstructorMethodsInterceptorPoint;
import org.xhy.sniffer.interceptor.InstanceMethodsInterceptorPoint;
import org.xhy.sniffer.interceptor.StaticMethodsInterceptorPoint;

import static net.bytebuddy.matcher.ElementMatchers.*;


public class SpringmvcCommonInstrumentation extends ClassEnhancePluginDefine {
    private static final String REST_CONTROLLER_NAME = "org.springframework.web.bind.annotation.RestController";

    private static final String MAPPING_PKG_PREFIX = "org.springframework.web.bind.annotation";
    private static final String MAPPING_SUFFIX = "Mapping";
    private static final String INTERCEPTOR = "org.xhy.sniffer.plugins.springmvc.interceptor.SpringmvcInterceptor";

    protected ClassMatch enhanceClass() {
        return AnnotationMatch.buildAnnotationMatch(REST_CONTROLLER_NAME);
    }

    @Override
    protected InstanceMethodsInterceptorPoint[] getInstanceMethodsInterceptorPoints() {
        return new InstanceMethodsInterceptorPoint[]{
                new InstanceMethodsInterceptorPoint() {
                    @Override
                    public ElementMatcher<MethodDescription> getMethodsMatcher() {
                        return  not(isStatic()).and(isAnnotatedWith(
                                nameStartsWith(MAPPING_PKG_PREFIX).and(nameEndsWith(MAPPING_SUFFIX))
                        ));
                    }

                    @Override
                    public String getMethodsInterceptor() {
                        return INTERCEPTOR;
                    }
                }
        };
    }

    @Override
    protected ConstructorMethodsInterceptorPoint[] getConstructorMethodsInterceptorPoints() {
        return null;
    }

    @Override
    protected StaticMethodsInterceptorPoint[] getStaticMethodsInterceptorPoints() {
        return new StaticMethodsInterceptorPoint[0];
    }
}
